var MYMODEL = null;
/**
 * 邹老师的前端 数据存储器 V1.0 
 * 存储到storage
 * qq:37798955@qq.com
 * @param {Object} tblname
 * @param {Object} model
 * @param {Object} idtype
 */

(function(e,t) {
		if ("object" == typeof exports && "object" == typeof module) module.exports.XCDBHelp = t;
		else if ("function" == typeof define && define.amd) define(t);	
		else e.XCDBHelp = t; //需要实例化
})(this,function (tblname, model, idtype) {
	this._tableName = "";
	this._err = '';
	this._where = null;
	this._select = null;
	this._model = null;
	//this._rs = ''; //结果集合 不能定义 因为很多结果会冲突
	this._columns = [];
	this._idtype = 'G';
	this.limitBegin = 0; //从哪个位置开始读取
	this.limitLen = -1; //n=-1 读取所有，n>-1 读取n条
	var _backuppath = 'backup.f'; //备份文件
	//初始化数据库
	this.init = function(tblname, model, idtype) {
		this._tableName = tblname;		
		//console.log("573"+tblname+JSON.stringify(model));

		//this._rs = arr;

		//自增类型还是guid类型
		if(idtype == null)
			this._idtype = 'G'
		else
			this._idtype = idtype.toUpperCase();
	}
	if(tblname)
		this.init(tblname, model, idtype);

	function commit(key) {
		//alert('zzz')
		var mydb = _STO.getItem('ALLTABLESTATUS');
		if(mydb == null) mydb = {};
		mydb[key] = new Date().Format();
		_STO.setItem('ALLTABLESTATUS', mydb);
	}


	//结构KEYID:{tablename:id}
	function getAutoID(tableName, idtype) {
		var idmap = _STO.getItem("KEYID"); //专门存放自增的keyid
		if(idmap == null)
			idmap = [];
		var oid = idmap[tableName];
		if(oid == null)
			oid = 0;
		var nid;
		//console.log(idtype)
		if(idtype == 'G') //init()
		{
			nid = getGuid();
			//console.log(nid)
		} else {
			nid = parseInt(oid) + 1;
			//console.log(nid)
		}

		idmap[tableName] = nid;
		_STO.setItem("KEYID", idmap);
		return oid, nid;
	}

	this.onErr = function(tx, e) {
		this._err = e;
		console.log(e.message);
	}
	this.batchreplace = function(callback) {
		var sub = _STO.getItem(this._tableName);
		if(callback)
			sub = callback(sub)
		_STO.setItem(this._tableName, sub);
	}
	//模型：当前库和历史库
	//当前库表名=key，记录是[]
	//当前库表名为_datekey：表名=key，记录是[]
	//_idkey 和_datekey 是插件的关键属性 ，自定义属性不能用_开头
	//修改当前对象
	this.setObj = function(obj) {
		//console.log('214:' + obj._idkey)
		var sub = _STO.getItem(this._tableName);
		if(_IS.isEmptyString(obj._idkey)) { //等于空时 自动赋值id
			obj._idkey = getAutoID(this._tableName, this._idtype);
		}
		//console.log('218:' + obj._idkey)
		obj._syschgdate = new Date().Format()
		if(sub == null)
			sub = {}
		delete sub[""];
		sub[obj._idkey] = obj;
		_STO.setItem(this._tableName, sub);
		
		commit(this._tableName);
		return obj._idkey
	}
	this.delObjById = function(id) {
		var sub = _STO.getItem(this._tableName);
		delete sub[id];
		_STO.setItem(this._tableName, sub);
	}
	this.clear = function() {
		_STO.setItem(this._tableName, {});
	}
	this.setList = function(rs) {
		for(i in rs) {
			this.setObj(rs[i])
		}
	}
	//修改历史对象
	function setHisObj(obj) {
		//(new Date()).format('yyyyMM')
		var key = obj._datekey + ":" + this._tableName;
		var sub = _STO.getItem(key);
		obj._syschgdate = new date().Format()
		sub[obj._idkey] = obj;
		commit(obj._idkey);
		_STO.setItem(key, sub);
	}
	this.setHisList = function(rs) {
		for(i in rs) {
			setHisObj(rs[i])
		}
	}
	//移动到历史记录
	this.mov2His = function(obj) {
		getObj(obj)
		setHisObj(obj)
	}

	function getListByIDs(tablename, idkeys) {
		var arr = []
		var sub = _STO.getItem(tablename); //sub={} or map	
		//console.log('getListByIDs')
		//console.log(tablename)
		//log(sub)
		var key;
		if(sub == null) return null;
		if(idkeys instanceof Array && idkeys.length > 0) {
			for(i in idkeys) {
				key = idkeys[i]
				if(sub.hasOwnProperty(key))
					arr.push(sub[key]);
			}
			//console.log("cccc"+key+sub[key])
		} else if(typeof(idkeys) == 'string') {

			if(sub.hasOwnProperty(idkeys))
				//arr[idkeys]=sub[idkeys];
				arr.push(sub[idkeys]);
		}
		return arr;
	}
	//通过id得到对象
	this.getObjByID = function(id) {
		if(id == null) return null;
		var objs = getListByIDs(this._tableName, id.toString())
		if(objs == null) return null;
		if(objs.length > 0)
			return objs[0];
		return null;
	}
	//通过id得到对象
	this.getListByID = function(ids) {
		return getListByIDs(this._tableName, ids)
	}
	//参数格式： datekey:"";ids:[ids]
	this.getHisListByID = function(datekey, ids) {
		var key = datekey + ":" + this._tableName;
		return getListByIDs(key, ids)
	}
	//通过查询条件筛选内部数据得到对象
	this.getList = function(callback) {
		var sub = _STO.getItem(this._tableName);
		return this.reduces(sub, callback);
	}
	//通过查询条件得到对象
	this.getHisList = function(datekey) {
		var key = datekey + ":" + this._tableName;
		var sub = _STO.getItem(key); //[]记录集合
		return this.reduces(sub);
	}

	this.where = function(where) {
		this._where = where;
		return this;
	}
	this.select = function(selectsql) {
		this._select = selectsql;
		return this;
	}
	//限定记录列表区间
	this.limit = function(begin, len) {
		this.limitBegin = begin;
		this.limitLen = len;
		return this;
	}

	//对外部的数据进行筛选
	//rs=map
	this.reduces = function(rs, callback) {
		//if(this._where == null) return rs;
		//		/log(this._where,'jsondb.js647:')
		//console.log(JSON.stringify(this._where))
		var newrs = [];
		//
		if(callback && callback.ini)
			callback.ini();
		if(rs) {
			//for(var i  in rs) {
			var begin = 0;
			var len = 0;
			this.limitBegin = this.limitBegin | 0;
			if(limitBegin > rs.length) {
				this.limitBegin = 0;
			} else {
				begin = this.limitBegin;
			}
			if((!this.limitLen) || this.limitLen < 0 || begin + this.limitLen > rs.length) {
				this.limitLen = rs.length - begin;
			}
			len = this.limitLen;
			for(var i = begin; i < len; i++) {
				if(rs[i]) {
					//console.log("ggg0"+i+JSON.stringify(rs[i]))
					//console.log("ggg0"+rs[i])
					//console.log(this._select);				
					var rc = reduce(rs[i], this._where);
					if(rc) {
						newrs.push(_AW.selectcols(rc, this._select))
						if(callback && callback.ing)
							callback.each(rc, i);
					}
				}
			}
		}
		if(callback && callback.finish)
			callback.finish();
		//console.log("ggg1")
		return newrs;
	}

	//key ='field(','field)','field[','field]','field=','field%','or'
	//,'field[%','field%]' 数组和map 不允许用特殊符号表示大小比较和模糊匹配
	//每条记录的属性与条件进行判断
	function reduce(rc, whereobj) {
		if(rc instanceof Array && rc.length > 0) {
			return null;
		}
		if(whereobj == null) {
			return rc;
		}
		if(whereobj instanceof Array && whereobj.length > 0) {
			for(var i = 0; i < whereobj.length; i++) {
				//for(var i in whereobj) {
				//console.log(JSON.stringify(whereobj[i]))
				var r = reduce(rc, whereobj[i]);
				if(r != null) return r;
			}
			//console.log("dd "+JSON.stringify(whereobj))
			return null;
		} else {
			if(typeof(whereobj) === 'string') { //不支持 string 类型的条件
				return rc;
			}
			for(var key in whereobj) {
				var v = whereobj[key];

				if(v == null || v === '') continue; //如果查询的值为空跳过
				//	console.log(key +' '+v+' '+rcv)

				if(key == "or") {
					//此时的wvalue=[条件]
					if(v instanceof Array && v.length > 0)
						return reduce(rc, v);
				} else {
					var m = '=';
					var n = 0;
					if((n = key.indexOf('=')) > 0)
						m = '=';
					else if((n = key.indexOf('(')) > 0)
						m = '(';
					else if((n = key.indexOf(')')) > 0)
						m = ')';
					else if((n = key.indexOf('[%')) > 0)
						m = '[%';
					else if((n = key.indexOf('%]')) > 0)
						m = '%]';
					else if((n = key.indexOf('[')) > 0)
						m = '[';
					else if((n = key.indexOf(']')) > 0)
						m = ']';
					else if((n = key.indexOf('%')) > 0)
						m = '%';

					if(n == -1)
						n = key.length;

					key = key.slice(0, n).replace(/(^\s*)|(\s*$)/g, "");
					var rcv = rc[key];
					if(_IS.isArray(rcv) || _IS.isMap(rcv)) continue; //如果是数组或者map类型跳过

					//console.log(key+' '+rcv+m+' '+v)

					if(typeof(rcv) == "undefined") {
						return null;
					} else if(typeof(rcv) == 'string') {
						//console.log(m + ' '+typeof(rcv) +' ' + rcv+' '+v+rcv.indexOf(v) )
						if((m == '=' && rcv == v) ||
							(m == '%' && rcv.indexOf(v) > -1) ||
							(m == '[%' && rcv.indexOf(v) == 0) ||
							(m == '%]' && rcv.slice(-v.length) == v) ||
							(m == '(' && rcv > v) || (m == ')' && rcv < v) ||
							(m == '[' && rcv >= v) || (m == ']' && rcv <= v)) {
							continue;
						} else {
							return null;
						}
					} else if(typeof(rcv) === 'number') {
						if((m == '=' && rcv == v) || (m == '(' && rcv > v) ||
							(m == ')' && rcv < v) || (m == '[' && rcv >= v) ||
							(m == ']' && rcv <= v)) {
							//console.log(key+' '+rcv+' '+m+' '+v)
							continue;
						} else {
							return null;
						}
					} else if(_IS.isBool(rcv)) {
						if((m == '=' && rcv == v)) {
							continue;
						} else {
							return null;
						}
					} else {
						console.log('条件表达式错误请检查')
						continue;
					}
				}
			}
			//console.log('ok'+key)
			return rc;
		}
	}
}